package hk.edu.uic.hejing.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import hk.edu.uic.hejing.entity.*;
import hk.edu.uic.hejing.service.*;
import hk.edu.uic.hejing.storage.StorageFileNotFoundException;
import hk.edu.uic.hejing.storage.StorageService;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Path;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author hejing
 * @since 2017-05-30
 */
@Controller
@RequestMapping("/teacher")
public class TeacherController {

    @Autowired
    private ITeacherService iTeacherService;
    @Autowired
    private IRuleService iRuleService;
    @Autowired
    private IRubricService iRubricService;
    @Autowired
    private StorageService storageService;
    @Autowired
    private IImportgroupService iImportgroupService;
    @Autowired
    private IStudentService iStudentService;
    @Autowired
    private IItemScoreService iItemScoreService;
    /**
     *  user login page
     * @param req
     * @return
     */
    @RequestMapping("/login")
    public String login(HttpServletRequest req) {
        if (req.getSession().getAttribute("user") != null) return "redirect:dashboard";
        return "login";
    }


    /**
     * user logout
     * @param req
     * @return
     */
    @RequestMapping("/logout")
    public String greeting(HttpServletRequest req) {
        req.getSession().setAttribute("user", null);
        return "login";
    }

    /**
     * teacher get into dashboard page
     * @param req
     * @return
     */
    @RequestMapping("/dashboard")
    public String dashboard(Model model,HttpServletRequest req) {
        if (req.getSession().getAttribute("user") == null) return "redirect:login";
        model.addAttribute("user", req.getSession().getAttribute("user"));
        model.addAttribute("rubrics",iRubricService.getAllRubrics());
        model.addAttribute("studentcategory",iStudentService.getStudentCategory());

        return "dashboard";
    }

    /**
     *  teacher login validation
     * @param session
     * @param email
     * @param password
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    @RequestMapping(value = "/signin", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String signin(HttpSession session,
                         @RequestParam(value = "email", required = true, defaultValue = "admin@uic.edu.hk") String email,
                         @RequestParam(value = "password", required = true, defaultValue = "admin") String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        Teacher t = new Teacher(password, email);
        System.out.println("user pass" + t.toString());
        Wrapper<Teacher> user = new EntityWrapper<Teacher>()
                .eq("email", t.getEmail())
                .eq("pass", t.getPass());
        Teacher teacher = iTeacherService.selectOne(user);
        if (teacher != null) {
            session.setAttribute("name", teacher.getName());
            session.setAttribute("uid", teacher.getId());
            session.setAttribute("email", teacher.getEmail());
            session.setAttribute("user", teacher);

            System.out.println(teacher.toString());
            return "redirect:/teacher/dashboard";
        }
        return "redirect:/teacher/login";
    }

    /**
     * teacher add new rubric for course
     * @param req
     * @return
     */
    @RequestMapping(value="/addschema", method = RequestMethod.POST)
    @ResponseBody
    public Object addSchema(HttpServletRequest req) {
        Teacher user = (Teacher) req.getSession().getAttribute("user");
        if (user == null) return "redirect:/teacher/login";
        String data = req.getParameter("d");
        JSONObject jsonObj = JSONObject.parseObject(data);
        Rubric rubric = new Rubric(jsonObj.get("title").toString(),jsonObj.get("applydate").toString());
        iRubricService.insert(rubric);
        int rubricid = rubric.getId();
        Rule rule = null;
        for (Map.Entry<String, Object> entry : jsonObj.entrySet()) {
//            System.out.println(entry.getKey() + ":" + entry.getValue());
            if (entry.getKey().equals("title") || entry.getKey().equals("applydate")) continue;
            rule = new Rule(rubricid,entry.getKey().toString(),Integer.parseInt(entry.getValue().toString()));
            iRuleService.insert(rule);
        }

        JSONObject result = new JSONObject();
        result.put("msg","ok");
        return result;
    }

    /**
     *  AJAX get rules by rubric id
     * @param req
     * @return
     */
    @RequestMapping(value = "/getrubricsbyid", method = RequestMethod.POST)
    @ResponseBody
    public Object getrubrics(HttpServletRequest req){
        Teacher user = (Teacher) req.getSession().getAttribute("user");
        if (user == null) return "redirect:/teacher/login";
        String rid = req.getParameter("rid");
        List<Rule> rules = iRuleService.getRulesByRid(Integer.parseInt(rid));
//        System.out.println("============rules size :"+rules.size());
        for(Rule attribute : rules) {
            System.out.println(attribute.toString());
        }
        JSONObject result = new JSONObject();
        String a = JSONObject.toJSONString(rules);
        System.out.println("JSONObject.toJSONString(rules): ==>"+a);

        result.put("msg","ok");
        result.put("rules",a);
        return result;
    }

    /**
     * teacher upload student excel
     * @param file
     * @param redirectAttributes
     * @return
     */
    @PostMapping("/uploadfile")
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
                                   @RequestParam("selectrubricid") String rubricid,
                                   RedirectAttributes redirectAttributes,HttpServletRequest req) throws IOException {
        Teacher user = (Teacher) req.getSession().getAttribute("user");
        if (user == null) return "redirect:/teacher/login";
//        storageService.deleteAll();
        storageService.store(file);
        Path filename = storageService.load(file.getOriginalFilename());
        System.out.print("============"+filename);

//        redirectAttributes.addFlashAttribute("message",
//                "You successfully uploaded " + file.getOriginalFilename() + "!");
        String s = file.getOriginalFilename().toString().split("\\.")[0];
        Date date = new Date();
        DateFormat format = new SimpleDateFormat("yyyyMMddhhmmss");
        String str = format.format(date); //2013-01-14
        s = s+str;
        s = s.replace("upload-dir\\","");
        dealWithExcel(filename.toString(),rubricid,s);
        return "redirect:/teacher/dashboard";
    }

    @ExceptionHandler(StorageFileNotFoundException.class)
    public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) {
        return ResponseEntity.notFound().build();
    }

    /**
     * load excel file and save student data into database
     * @param filename
     * @param rubricid
     * @param classes
     * @return
     * @throws IOException
     */
    protected boolean dealWithExcel(String filename, String rubricid, String classes) throws IOException {
        HSSFWorkbook book = new HSSFWorkbook(new FileInputStream(ResourceUtils.getFile(filename)));
        List<Student> list = new ArrayList<Student>();

        HSSFSheet sheet = book.getSheetAt(0);

        for(int i=2; i<sheet.getLastRowNum()+1; i++) {
            HSSFRow row = sheet.getRow(i);
            String studentid = row.getCell(0).getStringCellValue();
            String ename = row.getCell(1).getStringCellValue();
            String cname = row.getCell(2).getStringCellValue();
            String gender = row.getCell(3).getStringCellValue();
            String email = row.getCell(4).getStringCellValue();
            String programme = row.getCell(5).getStringCellValue();
            Integer studyyear = (int) row.getCell(6).getNumericCellValue();
//            Student student = new Student( studentid,  ename,  cname,  gender,  email,  programme, studyyear,  Integer.parseInt(rubricid),  groupid);

            list.add(new Student( studentid,  ename,  cname,  gender,  email,  programme, studyyear,  Integer.parseInt(rubricid),  classes));
        }

        return iStudentService.insertBatch(list);


    }

    @RequestMapping("/mark/{classes}/{rubricid}")
    public String mark(@PathVariable(value="classes") String classes,
                       @PathVariable(value="rubricid") int rubricid,
                       HttpServletRequest req,
                       Model model
                        ){
        Teacher user = (Teacher) req.getSession().getAttribute("user");
        if (user == null) return "redirect:/teacher/login";
        model.addAttribute("rules",iRuleService.getRulesByRid(rubricid));
        model.addAttribute("students",iStudentService.getStudentByRubricidClasses(rubricid,classes));
        model.addAttribute("classes",classes);


        Wrapper<ItemScore> itemScoreWrapper = new EntityWrapper<ItemScore>()
                .eq("rubricid",rubricid)
                .eq("classes",classes);

        model.addAttribute("scores",iItemScoreService.selectList(itemScoreWrapper));
//        List<ItemScore> a = iItemScoreService.selectList(itemScoreWrapper);
//        List<Rule> r = iRuleService.getRulesByRid(rubricid);
//        List<Student> a = iStudentService.getStudentByRubricid(rubricid);

//        for (ItemScore S: a ) {
//            System.out.println(S.getX() +"  : "+ S.getClasses());
//        }
//
//        for (Rule R: r ) {
//            System.out.println(R.toString());
//        }
        return "mark";
    }

    @RequestMapping("/mark/detail/{classes}/{studentid}")
    public String markDetail(@PathVariable(value="classes") String classes,
                       @PathVariable(value="studentid") String  studentid,
                       HttpServletRequest req,
                       Model model
    ) {
        Teacher user = (Teacher) req.getSession().getAttribute("user");
        if (user == null) return "redirect:/teacher/login";


        Wrapper<ItemScore> itemScoreWrapper = new EntityWrapper<ItemScore>()
                .eq("studentid",studentid)
                .eq("classes",classes);

        Wrapper<Student> stu = new EntityWrapper<Student>()
                .eq("studentid", studentid)
                .eq("classes", classes);
        Student student = iStudentService.selectOne(stu);


        List<ItemScore> list = iItemScoreService.selectList(itemScoreWrapper);
        int rubricid = list.get(0).getRubricid();
        model.addAttribute("rules",iRuleService.getRulesByRid(rubricid));

        model.addAttribute("items",list);
        model.addAttribute("student",student);


        List<ItemScore> a = iItemScoreService.selectList(itemScoreWrapper);

        for (ItemScore S: a ) {
            System.out.println(S.toString());
        }
        return "hello";

    }


    @RequestMapping(value="/updateScore", method = RequestMethod.POST)
    @ResponseBody
    public Object updateScore(HttpServletRequest req) {
        Teacher user = (Teacher) req.getSession().getAttribute("user");
        if (user == null) return "redirect:/teacher/login";
        String data = req.getParameter("d");
        JSONArray jsonArr = JSONObject.parseArray(data);

        List<ItemScore> list = JSONObject.parseArray(jsonArr+"", ItemScore.class);

        int rid = list.get(0).getRubricid();
        String sid = list.get(0).getStudentid();
        System.out.println(rid +":"+sid);
        iItemScoreService.deleteItemScoreBySidRid(sid,rid);
        iItemScoreService.insertBatch(list);
//        iItemScoreService.deleteBatchIds()
        for (ItemScore is : list) {
            System.out.println(is.getItem() + " : " + is.getScore() +" ： " + is.getStudentid()+" ： " + is.getRubricid());
        }



//        Rubric rubric = new Rubric(jsonObj.get("title").toString(),jsonObj.get("applydate").toString());
//        iRubricService.insert(rubric);
//        int rubricid = rubric.getId();
//        Rule rule = null;
//        for (Map.Entry<String, Object> entry : jsonObj.entrySet()) {
////            System.out.println(entry.getKey() + ":" + entry.getValue());
//            if (entry.getKey().equals("title") || entry.getKey().equals("applydate")) continue;
//            rule = new Rule(rubricid,entry.getKey().toString(),Integer.parseInt(entry.getValue().toString()));
//            iRuleService.insert(rule);
//        }

        JSONObject result = new JSONObject();
        result.put("msg","ok");
        return result;
    }


//    ========belowing just for testing=====================

    @RequestMapping("/user")
    public String user(HttpServletRequest req) {
        if (req.getSession().getAttribute("user") != null) return "redirect:user";
        return "user";
    }

    @RequestMapping(value="/add")
    public String add() throws UnsupportedEncodingException, NoSuchAlgorithmException {
        Teacher teacher = new Teacher("admin", "admin", "admin@uic.edu.hk");
        JSONObject result = new JSONObject();
        result.put("result", iTeacherService.insert(teacher));
        System.out.println(result);

        return "login";
    }

    @RequestMapping(value = "/addUser", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public Object addUser(@RequestParam("username") String username,
                          @RequestParam(value = "password", required = true, defaultValue = "123") String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {

        Teacher teacher = new Teacher(username, password, "admin@uic.edu.hk");
        JSONObject result = new JSONObject();

        //result.put("result", iTeacherService.deleteAll());
        //System.out.println(result);

        result.put("result", iTeacherService.insert(teacher));
        System.out.println(result);
        return "login";
    }

    @RequestMapping("/hello")
    public String hello(HttpServletRequest req) {

        return "hello";
    }

}
